package com.example.innerclass1;

/**
 * 演示成员内部类的使用
 */
public class MemberInnerClass01 {
    public static void main(String[] args) {
        outer08 outer08 = new outer08();
        /*
        说明：
        1.成员内部类是定义在外部类的成员位置，并且没有static修饰。
        2.可以直接访问外部类的所有成员，包含私有的
        3.可以添加任意访问修饰符(public、protected、默认、private)，因为它的地位就是一个成员。
        4.作用域和外部类的其他成员一样，为整个类体 比如前面案例，在外部类的成员方法中创建成员内部类对象，再调用方法.
        5.成员内部类---访问---->外部类成员(比如：属性)访问方式：直接访问
        6.外部类---访问------>成员内部类(说明)访问方式：创建对象，再访问
        7.外部其他类---访问---->成员内部类
        8.如果外部类和内部类的成员重名时，内部类访问的话，默认遵循就近原则，如 果想访问外部类的成员，则可以使用(外部类名.this.成员)去访问
         */


        //7.外部其他类---访问---->成员内部类
        // 第一种方式
        // outer08.new Inner08(); 相当于把 new Inner08()当做是outer08成员
        // 这就是一个语法，不要特别的纠结.
        outer08.Inner08 inner081 = outer08.new Inner08();
        inner081.m1();
        // 第二方式 在外部类中，编写一个方法，可以返回 Inner08对象
        outer08.Inner08 inner082 = outer08.getInner08();
        inner082.m1();


    }
}

class outer08 {//外部类
    //私有属性
    private int n1 = 10;
    public String name = "jack";

    //私有方法
    private void hi() {
        System.out.println("hello,word");
    }

    //1.成员内部类是定义在外部类的成员位置，并且没有static修饰。 此时我们的内部类就是定义在属性的位置上的
    //3.可以添加任意访问修饰符(public、protected、默认、private)，因为它的地位就是一个成员。
    public class Inner08 {
        private int n1 = 66;

        public void m1() {
            //2.可以直接访问外部类的所有成员，包含私有的
            //直接访问外部类的私有属性和私有方法
            System.out.println(n1);
            hi();

            //5.成员内部类---访问---->外部类成员(比如：属性)访问方式：直接访问
            //访问外部类的私有属性
            System.out.println(name);
            //访问外部类的私有方法
            hi();


            //8.如果外部类和内部类的成员重名时，内部类访问的话，默认遵循就近原则，如 果想访问外部类的成员，则可以使用(外部类名.this.成员)去访问
            System.out.println(outer08.this.n1);//访问的是外部类的n1
            System.out.println(n1);//因为遵守就近原则，所以访问的是，Inner08中的n1
            System.out.println(Inner08.this.n1);//访问的也是Inner08中的n1
        }
    }

    //编写一个方法，返回一个Inner08的对象
    public Inner08 getInner08() {
        return new Inner08();
    }

    //4.作用域和外部类的其他成员一样，为整个类体 比如前面案例，在外部类的成员方法中创建成员内部类对象，再调用方法.
    //6.外部类---访问------>成员内部类(说明)访问方式：创建对象，再访问
    public void ok() {
        //外部类使用内部类成员,先创建对象，然后使用相关属性或者方法
        Inner08 inner08 = new Inner08();
        inner08.m1();
        System.out.println(inner08.n1);//可以直接访问成员内部类的私有属性
    }
}
